<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title> 聊天界面</title>
    <!-- 修改 highlight.js 的引入顺序和方式 -->
    <!-- 引入 highlight.js -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
    <!-- 引入常用编程语言支持 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/python.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/javascript.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/java.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/cpp.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/xml.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/css.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/sql.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/bash.min.js"></script>
    <!-- 引入 marked -->
    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>

    <style>
        /* 修改主题色和整体风格 */
        :root {
            --primary-color: #3B82F6;  /* 改为浅蓝色 */
            --primary-hover: #2563EB;  /* 深一点的蓝色用于悬停 */
            --bg-color: #F9FAFB;
            --card-bg: #FFFFFF;
            --border-color: #E5E7EB;
            --text-primary: #111827;
            --text-secondary: #4B5563;
            --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
            --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
            --radius-lg: 12px;
            --radius-md: 8px;
        }

        body {
            font-family: 'Source Han Sans CN', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: var(--bg-color);
            height: 100vh;
            display: flex;
            flex-direction: column;
            color: var(--text-primary);
            line-height: 1.2;
            font-weight: 300;
        }
        
        /* 美化头部 */
        .header {
            background: var(--card-bg);
            padding: 1rem 1.5rem;
            border-bottom: 1px solid var(--border-color);
            backdrop-filter: blur(8px);
            position: sticky;
            top: 0;
            z-index: 100;
            display: flex;
            align-items: center;
            box-shadow: 0 1px 3px rgba(0,0,0,0.05);
            justify-content: space-between;
        }
        
        .logo {
            color: var(--primary-color);
            font-size: 1.5rem;
            font-weight: 500;
            letter-spacing: -0.5px;
        }
        
        .service-status {
            display: flex;
            align-items: center;
            gap: 12px;  /* 增加间距 */
        }
        
        .model-selection {
            display: flex;
            gap: 0.5rem;
            align-items: center;
        }
        
        #modelSelect {
            background: var(--bg-color);
            border: 1px solid var(--border-color);
            padding: 0.5rem 1rem;
            border-radius: var(--radius-md);
            min-width: 200px;
            transition: all 0.2s;
        }
        
        #modelSelect:hover {
            border-color: #3B82F6;
        }
        
        #refreshModels {
            background: var(--bg-color);
            border: 1px solid var(--border-color);
            padding: 0.5rem;
            border-radius: var(--radius-md);
            cursor: pointer;
            transition: all 0.2s;
        }
        
        #refreshModels:hover {
            background: #3B82F6;
        }
        
        .status-button {
            padding: 8px 16px;
            border-radius: 6px;
            border: none;
            cursor: pointer;
            font-size: 14px;
            display: flex;
            align-items: center;
            gap: 8px;
            transition: all 0.2s;
        }
        
        .status-button.running {
            background-color: #10B981;
            color: white;
        }
        
        .status-button.stopped {
            background-color: #EF4444;
            color: white;
        }
        
        .status-button.checking {
            background-color: #F3F4F6;
            color: #374151;
        }
        
        .status-button:hover {
            opacity: 0.9;
        }
        
        .main-container {
            flex: 1;
            display: flex;
            max-width: 1400px;
            margin: 0 auto;
            width: 100%;
            padding: 20px;
            gap: 20px;
        }
        
        .chat-container {
            flex: 1;
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 6px rgba(0,0,0,0.1);
            display: flex;
            flex-direction: column;
            height: calc(100vh - 140px);
        }
        
        .messages {
            flex: 1;
            overflow-y: auto;
            padding: 20px;
            background-color: #F9FAFB;
            scroll-behavior: smooth;
        }
        
        .message {
            margin-bottom: 20px;
            display: flex;
            align-items: flex-start;
            animation: fadeIn 0.3s ease-out;
            padding: 0 20px;
        }
        
        /* 用户消息靠右 */
        .user-message {
            flex-direction: row-reverse;
        }
        
        /* 调整头像间距 */
        .user-message .avatar {
            margin-left: 16px;
            margin-right: 0;
        }
        
        .bot-message .avatar {
            margin-right: 16px;
            margin-left: 0;
        }
        
        /* 美化消息气泡 */
        .message-content {
            flex: 0 1 auto;
            padding: 12px 16px;
            border-radius: var(--radius-lg);
            box-shadow: var(--shadow-sm);
            max-width: 85%;
            min-width: 60px;
        }
        
        .user-message .message-content {
            background: var(--primary-color);
            color: white;
        }
        
        .bot-message .message-content {
            background: var(--card-bg);
            border: 1px solid var(--border-color);
        }
        
        /* 思考中的消息样式 */
        .message.thinking .message-content {
            min-width: 60px;
            background-color: #F9FAFB;
            border: 1px solid #E5E7EB;
        }
        
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }
        
        .avatar {
            width: 36px;
            height: 36px;
            border-radius: 50%;
            margin-right: 12px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            overflow: hidden;
        }
        
        .avatar img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        
        .bot-avatar {
            background-color: transparent;
        }
        
        .user-avatar {
            background-color: transparent;
        }
        
        .input-container {
            padding: 1rem;
            background: var(--card-bg);
            border-top: 1px solid var(--border-color);
        }
        
        .input-wrapper {
            display: flex;
            align-items: center;
            background: var(--bg-color);
            border: 1px solid var(--border-color);
            border-radius: var(--radius-lg);
            padding: 0.5rem;
            transition: all 0.2s;
        }
        
        .input-wrapper:focus-within {
            border-color: var(--primary-color);
            box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.1);
        }
        
        #user-input {
            flex: 1;
            border: none;
            outline: none;
            padding: 0.75rem;
            font-size: 1rem;
            background: transparent;
            line-height: 1.5;
            font-family: 'Source Han Sans CN', inherit;
        }
        
        .send-button, .stop-button {
            padding: 0.75rem 1.25rem;
            border-radius: var(--radius-md);
            font-weight: 500;
            transition: all 0.2s;
        }
        
        .send-button {
            background: var(--primary-color);
        }
        
        .send-button:hover {
            background: var(--primary-hover);
        }
        
        .stop-button {
            background-color: #EF4444;
            color: white;
            border: none;
            cursor: pointer;
            margin-left: 8px;
            display: none;
        }
        
        .stop-button:hover {
            background-color: #DC2626;
        }
        
        .sidebar {
            width: 280px;
            background: var(--card-bg);
            box-shadow: var(--shadow-md);
            display: flex;
            flex-direction: column;
            margin-right: 20px;
            border-radius: var(--radius-lg);
            overflow: hidden;
        }
        
        .new-chat-btn {
            margin: 1rem;
            padding: 0.75rem;
            background: #3B82F6;
            color: white;
            border: none;
            border-radius: var(--radius-md);
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 0.5rem;
        }
        
        .new-chat-btn:hover {
            background: #2563EB;
        }
        
        .history-container {
            flex: 1;
            overflow-y: auto;
            padding: 8px;
        }
        
        .history-item {
            margin: 0.25rem 0.75rem;
            padding: 0.75rem 1rem;
            border-radius: var(--radius-md);
            cursor: pointer;
            display: flex;
            align-items: center;
            color: #374151;
            transition: all 0.2s;
        }
        
        .history-item:hover {
            background: var(--bg-color);
        }
        
        .history-item.active {
            background: #3B82F6;
            color: white;
        }
        
        .history-item i {
            margin-right: 8px;
            font-size: 16px;
        }
        
        .history-item span {
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            flex: 1;
        }
        
        /* 美化思考过程区域 */
        .thinking-section {
            margin: 0.75rem 0;
        }
        
        .thinking-header {
            background: var(--bg-color);
            border-radius: var(--radius-md);
            padding: 0.75rem 1rem;
            font-size: 13px;
            gap: 8px;
            display: flex;
            align-items: center;
            cursor: pointer;
            user-select: none;
            font-weight: 500;
        }
        
        .thinking-header.collapsed svg {
            transform: rotate(-90deg);
        }
        
        .thinking-header:hover {
            background-color: #E5E7EB;
        }
        
        .thinking-header svg {
            min-width: 16px;
            height: 16px;
            transition: transform 0.2s;
        }
        
        .thinking-header .title-text {
            display: flex;
            align-items: center;
            gap: 4px;
        }
        
        .thinking-content {
            background: var(--bg-color);
            border-radius: 0 0 var(--radius-md) var(--radius-md);
            padding: 1rem;
            font-size: 13px;
            line-height: 1.5;
            border: 1px solid #E5E7EB;
            border-top: none;
            display: none;
        }
        
        .thinking-content.visible {
            display: block;
        }
        
        /* 添加 Markdown 样式 */
        .markdown-content {
            line-height: 1.6;
            font-size: 15px;
        }
        
        .markdown-content p {
            margin: 0.8em 0;
        }
        
        /* 美化代码块 */
        .markdown-content pre {
            background: var(--bg-color);
            border-radius: var(--radius-md);
            border: 1px solid var(--border-color);
            margin: 12px 0;
            padding: 16px;
            position: relative;
            overflow-x: auto;
            white-space: pre !important;
        }
        
        /* 代码块样式 */
        .markdown-content pre code {
            padding: 0;
            background: transparent;
            font-family: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;
            font-size: 14px;
            line-height: 1.5;
            tab-size: 4;
            -moz-tab-size: 4;
            white-space: pre !important;  /* 强制保持原始格式 */
            display: block;
            overflow-x: auto;
        }
        
        /* 美化复制按钮 */
        .copy-button {
            position: absolute;
            top: 8px;
            right: 8px;
            opacity: 0;
            transition: opacity 0.2s, background-color 0.2s;
            background: var(--card-bg);
            color: var(--text-secondary);
            font-size: 12px;
            padding: 0.5rem 0.75rem;
            border: 1px solid var(--border-color);
            border-radius: var(--radius-md);
            cursor: pointer;
            z-index: 1;
        }
        
        .markdown-content pre:hover .copy-button {
            opacity: 1;
        }
        
        .copy-button:hover {
            background: var(--primary-color);
            color: white;
            border-color: var(--primary-color);
        }
        
        /* 行内代码样式 */
        .markdown-content code:not(pre code) {
            background-color: rgba(175, 184, 193, 0.2);
            padding: 0.2em 0.4em;
            border-radius: 6px;
            font-family: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;
            font-size: 85%;
            font-weight: 300;
        }
        
        .markdown-content ul, .markdown-content ol {
            padding-left: 1.5em;
            margin: 0.5em 0;
        }
        
        .markdown-content blockquote {
            margin: 0.8em 0;
            padding-left: 1em;
            border-left: 4px solid #E5E7EB;
            color: #6B7280;
        }
        
        .markdown-content h1, 
        .markdown-content h2, 
        .markdown-content h3, 
        .markdown-content h4, 
        .markdown-content h5, 
        .markdown-content h6 {
            margin: 0.3em 0 0.2em;
            line-height: 1.2;
            font-weight: 500;
        }
        
        /* 思考中的动画样式 */
        .thinking-indicator {
            display: flex;
            align-items: center;
            gap: 6px;
            padding: 4px 8px;
        }
        
        .thinking-indicator .dot {
            width: 6px;
            height: 6px;
            background-color: #6B7280;
            border-radius: 50%;
            animation: bounce 1.4s infinite ease-in-out;
            opacity: 0.6;
        }
        
        .thinking-indicator .dot:nth-child(1) {
            animation-delay: -0.32s;
        }
        
        .thinking-indicator .dot:nth-child(2) {
            animation-delay: -0.16s;
        }
        
        @keyframes bounce {
            0%, 80%, 100% { 
                transform: scale(0);
            } 
            40% { 
                transform: scale(1);
            }
        }
        
        /* 美化自定义 prompt 区域 */
        .custom-prompt-container {
            background: var(--bg-color);
            border-radius: var(--radius-md);
            margin: 1rem;
        }
        
        .custom-prompt-header {
            padding: 0.75rem 1rem;
            border-bottom: 1px solid var(--border-color);
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-weight: 500;
        }
        
        .custom-prompt-header span {
            font-size: 14px;
            color: #374151;
            font-weight: 500;
        }
        
        .save-prompt-btn {
            padding: 4px 8px;
            background-color: #3B82F6;
            color: white;
            border: none;
            border-radius: 4px;
            font-size: 12px;
            cursor: pointer;
        }
        
        .save-prompt-btn:hover {
            background-color: #2563EB;
        }
        
        #custom-prompt {
            width: 100%;
            height: 120px;
            padding: 0.75rem;
            border: none;
            resize: vertical;
            font-family: 'Source Han Sans CN', inherit;
            font-size: 14px;
            line-height: 1.5;
            color: #374151;
        }
        
        #custom-prompt:focus {
            outline: none;
        }
        
        /* 使用 Medium 字重的元素 */
        .logo,
        .thinking-header,
        .custom-prompt-header span,
        .history-item.active,
        .markdown-content h1, 
        .markdown-content h2, 
        .markdown-content h3, 
        .markdown-content h4, 
        .markdown-content h5, 
        .markdown-content h6,
        .markdown-content strong {
            font-weight: 500;
        }
        
        /* 代码使用 Light 字重 */
        .markdown-content code {
            font-family: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;
            font-weight: 300;
        }
        
        /* 代码标题使用 Medium 字重 */
        .markdown-content pre {
            font-family: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;
            font-weight: 500;
        }
        
        /* 重要内容使用 Medium 字重 */
        .markdown-content strong {
            font-family: 'Source Han Sans CN';
            font-weight: 500;
            color: #1a1a1a;  /* 稍微加深颜色 */
        }
        
        /* 用户消息中的加粗内容保持白色 */
        .user-message .markdown-content strong {
            color: white;
        }
        
        /* 思考内容中的加粗内容使用不同颜色 */
        .thinking-content strong {
            color: #3B82F6;  /* 思考内容中的加粗文字也使用新主题色 */
        }
        
        .model-select {
            padding: 8px 12px;
            border-radius: 6px;
            border: 1px solid #E5E7EB;
            background-color: white;
            font-size: 14px;
            min-width: 160px;
            cursor: pointer;
            transition: all 0.2s;
        }
        
        .model-select:disabled {
            background-color: #F3F4F6;
            cursor: not-allowed;
        }
        
        .model-select:not(:disabled):hover {
            border-color: #3B82F6;
        }
        
        /* 添加响应式设计 */
        @media (max-width: 768px) {
            .main-container {
                flex-direction: column;
            }
            
            .sidebar {
                width: 100%;
                margin-bottom: 1rem;
            }
            
            .message-content {
                max-width: 90%;
            }
        }
    </style>
</head>
<body>
    <div class="header">
        <div class="logo">Ollama部署模型可视化by左岚</div>
        <div class="service-status">
            <div class="model-selection">
                <select id="modelSelect">
                    <option value="">加载中...</option>
                </select>
                <button id="refreshModels" title="刷新模型列表">
                    🔄 刷新
                </button>
            </div>
            <button id="ollama-status" class="status-button" onclick="toggleOllama()">
                检查 Ollama 状态...
            </button>
        </div>
    </div>
    
    <div class="main-container">
        <div class="sidebar">
            <button class="new-chat-btn" onclick="startNewChat()">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M12 4V20M4 12H20" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                </svg>
                开启新对话
            </button>
            
            <!-- 添加自定义 prompt 区域 -->
            <div class="custom-prompt-container">
                <div class="custom-prompt-header">
                    <span>自定义 Prompt</span>
                    <button class="save-prompt-btn" onclick="saveCustomPrompt()">保存</button>
                </div>
                <textarea id="custom-prompt" placeholder="在这里输入您的自定义 prompt..."></textarea>
            </div>
            
            <div class="history-container" id="history-container">
                <!-- 历史记录将通过 JavaScript 动态添加 -->
            </div>
        </div>

        <div class="chat-container">
            <div class="messages" id="chat-container">
                <!-- 移除初始欢迎消息 -->
            </div>
            
            <div class="input-container">
                <div class="input-wrapper">
                    <input type="text" id="user-input" placeholder="输入您的消息...">
                    <button class="send-button" onclick="sendMessage()" id="send-button">发送</button>
                    <button class="stop-button" onclick="stopGeneration()" id="stop-button" style="display: none;">停止</button>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 配置 marked 以更好地处理代码块和缩进
        marked.setOptions({
            highlight: function(code, lang) {
                if (lang && hljs.getLanguage(lang)) {
                    try {
                        // 保持原始缩进
                        return hljs.highlight(code, { language: lang }).value;
                    } catch (err) {}
                }
                return hljs.highlightAuto(code).value;
            },
            breaks: true,
            gfm: true,
            langPrefix: 'hljs language-',
            pedantic: false,
            smartLists: true,
            smartypants: false
        });

        function addMessage(message, isUser, data = null) {
            const chatContainer = document.getElementById('chat-container');
            const messageDiv = document.createElement('div');
            messageDiv.className = `message ${isUser ? 'user-message' : 'bot-message'}`;
            
            const avatar = document.createElement('div');
            avatar.className = `avatar ${isUser ? 'user-avatar' : 'bot-avatar'}`;
            avatar.innerHTML = `<img src="/static/${isUser ? 'lunai.jpg' : 'lunai.jpg'}" alt="${isUser ? 'User' : 'Bot'}">`;
            
            const content = document.createElement('div');
            content.className = 'message-content';
            
            // 检查消息是否包含 think 标签
            const thinkMatch = message.match(/<think>(.*?)<\/think>/s);
            // 只处理多余的换行符，保留缩进
            const mainContent = message.replace(/<think>.*?<\/think>/s, '')
                .trim()
                .replace(/\n\s*\n+/g, '\n');  // 只替换连续的空行，不处理缩进
            
            // 创建 markdown 内容容器
            const markdownContent = document.createElement('div');
            markdownContent.className = 'markdown-content';
            
            // 如果存在思考过程，先添加思考部分
            if (thinkMatch && thinkMatch[1]) {
                const thinkingSection = document.createElement('div');
                thinkingSection.className = 'thinking-section';
                
                const thinkingHeader = document.createElement('div');
                thinkingHeader.className = 'thinking-header collapsed';
                thinkingHeader.innerHTML = `
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    </svg>
                    <span class="title-text">查看思考过程</span>
                `.trim();
                
                const thinkingContent = document.createElement('div');
                thinkingContent.className = 'thinking-content';
                // 对思考内容也只处理多余的换行符
                const processedThinkContent = thinkMatch[1]
                    .trim()
                    .replace(/\n\s*\n+/g, '\n');  // 只替换连续的空行，不处理缩进
                thinkingContent.innerHTML = marked.parse(processedThinkContent);
                
                // 添加点击事件来切换显示/隐藏
                thinkingHeader.addEventListener('click', () => {
                    thinkingHeader.classList.toggle('collapsed');
                    thinkingContent.classList.toggle('visible');
                });
                
                thinkingSection.appendChild(thinkingHeader);
                thinkingSection.appendChild(thinkingContent);
                content.appendChild(thinkingSection);
            }
            
            // 使用 marked 解析 markdown
            if (isUser) {
                markdownContent.textContent = mainContent;
            } else {
                // 对代码块进行特殊处理
                const rendered = marked.parse(mainContent);
                markdownContent.innerHTML = rendered;
                
                // 处理所有代码块
                markdownContent.querySelectorAll('pre code').forEach((block) => {
                    // 保持原始缩进
                    const code = block.textContent;
                    block.textContent = code;  // 重新设置文本以保持缩进
                    
                    // 添加复制按钮
                    const pre = block.parentElement;
                    const copyButton = document.createElement('button');
                    copyButton.className = 'copy-button';
                    copyButton.innerHTML = '复制';
                    copyButton.onclick = () => {
                        navigator.clipboard.writeText(code);  // 使用原始代码
                        copyButton.innerHTML = '已复制';
                        setTimeout(() => copyButton.innerHTML = '复制', 2000);
                    };
                    pre.appendChild(copyButton);
                    
                    // 应用代码高亮
                    hljs.highlightBlock(block);
                });
            }
            
            content.appendChild(markdownContent);
            
            messageDiv.appendChild(avatar);
            messageDiv.appendChild(content);
            chatContainer.appendChild(messageDiv);
            chatContainer.scrollTop = chatContainer.scrollHeight;
            
            // 保存到当前会话
            if (currentConversationId) {
                const conversation = conversations.find(conv => conv.id === currentConversationId);
                if (conversation) {
                    conversation.messages.push({
                        content: message,
                        isUser: isUser,
                        timestamp: new Date().toISOString() // 添加消息时间戳
                    });
                    
                    if (isUser && conversation.title === "新对话" && conversation.messages.length === 1) {
                        conversation.title = message.substring(0, 20) + (message.length > 20 ? "..." : "");
                        updateHistoryDisplay();
                    }
                    
                    saveConversations(); // 保存更新
                }
            }
        }

        async function sendMessage() {
            const isRunning = await checkOllamaStatus();
            if (!isRunning) {
                alert('Ollama 服务未运行，请先启动服务');
                return;
            }
            
            const selectedModel = document.getElementById('modelSelect').value;
            if (!selectedModel) {
                alert('请先选择一个模型');
                return;
            }

            const input = document.getElementById('user-input');
            const message = input.value.trim();
            
            if (!message) return;
            
            addMessage(message, true);
            input.value = '';
            
            // 显示思考中的状态
            const thinkingDiv = document.createElement('div');
            thinkingDiv.className = 'message bot-message thinking';
            thinkingDiv.innerHTML = `
                <div class="avatar bot-avatar">
                    <img src="/static/lunai.jpg" alt="Bot">
                </div>
                <div class="message-content">
                    <div class="thinking-indicator">
                        <span class="dot"></span>
                        <span class="dot"></span>
                        <span class="dot"></span>
                    </div>
                </div>
            `;
            document.getElementById('chat-container').appendChild(thinkingDiv);
            
            // 显示停止按钮，隐藏发送按钮
            document.getElementById('send-button').style.display = 'none';
            document.getElementById('stop-button').style.display = 'inline-block';
            document.getElementById('user-input').disabled = true;
            
            try {
                const customPrompt = document.getElementById('custom-prompt').value;
                const response = await fetch('http://localhost:5000/chat', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ 
                        message: message,
                        customPrompt: customPrompt,
                        model: selectedModel
                    })
                });
                
                // 移除思考中的状态
                thinkingDiv.remove();
                
                const data = await response.json();
                
                if (data.status === 'success') {
                    addMessage(data.response, false, data);
                } else {
                    addMessage('发生错误: ' + data.response, false);
                }
            } catch (error) {
                // 移除思考中的状态
                thinkingDiv.remove();
                addMessage('发生错误: ' + error.message, false);
            } finally {
                // 恢复按钮状态
                document.getElementById('send-button').style.display = 'inline-block';
                document.getElementById('stop-button').style.display = 'none';
                document.getElementById('user-input').disabled = false;
            }
        }

        document.getElementById('user-input').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                sendMessage();
            }
        });

        // 添加新的历史记录管理功能
        let conversations = [];
        let currentConversationId = null;

        function startNewChat() {
            currentConversationId = Date.now().toString();
            const selectedModel = document.getElementById('modelSelect').value;
            
            const conversation = {
                id: currentConversationId,
                title: "新对话",
                messages: [],
                timestamp: new Date().toISOString(),
                model: selectedModel // 保存当前选择的模型
            };
            
            conversations.unshift(conversation);
            saveConversations();
            
            document.getElementById('chat-container').innerHTML = '';
            updateHistoryDisplay();
        }

        function updateHistoryDisplay() {
            const historyContainer = document.getElementById('history-container');
            historyContainer.innerHTML = conversations.map(conv => `
                <div class="history-item ${conv.id === currentConversationId ? 'active' : ''}" 
                     onclick="loadConversation('${conv.id}')">
                    <i>💬</i>
                    <span>${conv.title}</span>
                    <button class="delete-chat" onclick="event.stopPropagation(); deleteConversation('${conv.id}')">
                        🗑️
                    </button>
                </div>
            `).join('');
        }

        function loadConversation(conversationId) {
            const conversation = conversations.find(conv => conv.id === conversationId);
            if (conversation) {
                currentConversationId = conversationId;
                
                // 加载对话内容
                const chatContainer = document.getElementById('chat-container');
                chatContainer.innerHTML = '';
                conversation.messages.forEach(msg => {
                    addMessage(msg.content, msg.isUser);
                });
                
                // 设置对应的模型
                const modelSelect = document.getElementById('modelSelect');
                if (conversation.model) {
                    // 检查模型是否存在于选项中
                    const modelExists = Array.from(modelSelect.options).some(option => option.value === conversation.model);
                    if (modelExists) {
                        modelSelect.value = conversation.model;
                    } else if (modelSelect.options.length > 0) {
                        // 如果模型不存在，选择第一个可用的模型
                        modelSelect.selectedIndex = 0;
                    }
                }
                
                updateHistoryDisplay();
            }
        }

        // 添加停止生成函数
        async function stopGeneration() {
            try {
                await fetch('http://localhost:5000/stop', {
                    method: 'POST'
                });
            } catch (error) {
                console.error('停止生成失败:', error);
            } finally {
                // 恢复按钮状态
                document.getElementById('send-button').style.display = 'inline-block';
                document.getElementById('stop-button').style.display = 'none';
                document.getElementById('user-input').disabled = false;
            }
        }

        // 保存自定义 prompt
        function saveCustomPrompt() {
            const prompt = document.getElementById('custom-prompt').value;
            localStorage.setItem('customPrompt', prompt);
            // 显示保存成功提示
            const saveBtn = document.querySelector('.save-prompt-btn');
            const originalText = saveBtn.innerHTML;
            saveBtn.innerHTML = '已保存';
            setTimeout(() => saveBtn.innerHTML = originalText, 2000);
        }

        // 切换 Ollama 服务状态
        async function toggleOllama() {
            const statusButton = document.getElementById('ollama-status');
            statusButton.className = 'status-button checking';
            statusButton.innerHTML = '正在处理...';
            
            const isRunning = await checkOllamaStatus();
            if (!isRunning) {
                try {
                    const response = await fetch('http://localhost:5000/start_ollama', {
                        method: 'POST'
                    });
                    const data = await response.json();
                    
                    if (data.status === 'success') {
                        const success = await checkOllamaStatus();
                        if (success) {
                            // 只在成功启动服务后获取一次模型列表
                            await fetchModels();
                        }
                    } else {
                        alert('启动 Ollama 服务失败: ' + data.message);
                    }
                } catch (error) {
                    alert('启动 Ollama 服务失败');
                    await checkOllamaStatus();
                }
            }
        }

        // 修改自动检查和启动服务的功能
        async function checkAndStartOllama() {
            try {
                const response = await fetch('/check_ollama');
                const data = await response.json();
                
                if (data.status !== 'running') {
                    await toggleOllama(); // 使用 toggleOllama 来启动服务
                }
            } catch (error) {
                console.error('检查Ollama服务状态失败:', error);
            }
        }

        // 页面加载时检查服务状态
        document.addEventListener('DOMContentLoaded', checkAndStartOllama);

        // 定期检查 Ollama 状态
        let statusCheckInterval;
        
        function startStatusCheck() {
            // 清除可能存在的旧定时器
            if (statusCheckInterval) {
                clearInterval(statusCheckInterval);
            }
            // 每30秒检查一次状态
            statusCheckInterval = setInterval(checkOllamaStatus, 30000);
        }
        
        // 修改页面加载时的初始化逻辑
        window.addEventListener('load', () => {
            const savedPrompt = localStorage.getItem('customPrompt');
            if (savedPrompt) {
                document.getElementById('custom-prompt').value = savedPrompt;
            }
            // 初始检查 Ollama 状态
            checkOllamaStatus();
            // 启动定期检查
            startStatusCheck();
            
            // 加载保存的对话，如果没有对话记录会自动创建新对话
            loadConversations();
        });

        // 获取可用模型列表
        async function fetchModels() {
            try {
                const response = await fetch('/models');
                const data = await response.json();
                if (data.status === 'success') {
                    const modelSelect = document.getElementById('modelSelect');
                    modelSelect.innerHTML = ''; // 清空现有选项
                    
                    data.models.forEach(model => {
                        const option = document.createElement('option');
                        option.value = model.name;
                        option.textContent = `${model.name} (${model.size || 'unknown size'})`;
                        modelSelect.appendChild(option);
                    });
                }
            } catch (error) {
                console.error('获取模型列表失败:', error);
            }
        }
        
        // 页面加载时获取一次
        document.addEventListener('DOMContentLoaded', fetchModels);

        // 刷新按钮点击事件
        document.getElementById('refreshModels').addEventListener('click', fetchModels);

        // 修改 checkOllamaStatus 函数
        async function checkOllamaStatus() {
            const statusButton = document.getElementById('ollama-status');
            try {
                const response = await fetch('http://localhost:5000/check_ollama');
                const data = await response.json();
                
                if (data.status === 'running') {
                    statusButton.className = 'status-button running';
                    statusButton.innerHTML = `
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                            <path d="M20 6L9 17L4 12" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                        </svg>
                        Ollama 运行中
                    `;
                    // 启用模型选择
                    document.getElementById('modelSelect').disabled = false;
                    return true;
                } else {
                    statusButton.className = 'status-button stopped';
                    statusButton.innerHTML = `
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                            <path d="M18 6L6 18M6 6L18 18" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                        </svg>
                        Ollama 未运行
                    `;
                    document.getElementById('modelSelect').disabled = true;
                    return false;
                }
            } catch (error) {
                statusButton.className = 'status-button stopped';
                statusButton.innerHTML = `
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                        <path d="M18 6L6 18M6 6L18 18" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    </svg>
                    检查失败
                `;
                document.getElementById('modelSelect').disabled = true;
                return false;
            }
        }

        // 修改保存对话函数
        async function saveConversations() {
            const conversation = conversations.find(conv => conv.id === currentConversationId);
            if (conversation) {
                try {
                    const response = await fetch(`/conversations/${conversation.id}`, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify(conversation)
                    });
                    const data = await response.json();
                    if (data.status !== 'success') {
                        console.error('保存对话失败');
                    }
                } catch (error) {
                    console.error('保存对话失败:', error);
                }
            }
        }

        // 修改加载对话函数
        async function loadConversations() {
            try {
                const response = await fetch('/conversations');
                const data = await response.json();
                if (data.status === 'success') {
                    conversations = data.conversations;
                    if (conversations.length > 0) {
                        currentConversationId = conversations[0].id;
                        updateHistoryDisplay();
                        loadConversation(currentConversationId);
                    } else {
                        // 只有在没有任何对话记录时才创建新对话
                        startNewChat();
                    }
                } else {
                    startNewChat();
                }
            } catch (error) {
                console.error('加载对话记录失败:', error);
                startNewChat();
            }
        }

        // 修改删除对话函数
        async function deleteConversation(id) {
            // 添加确认对话框
            const conversation = conversations.find(conv => conv.id === id);
            const confirmMessage = `确定要删除对话 "${conversation?.title || '未命名对话'}" 吗？\n此操作不可恢复。`;
            
            if (!confirm(confirmMessage)) {
                return; // 如果用户点击取消，则不执行删除
            }
            
            try {
                const response = await fetch(`/conversations/${id}`, {
                    method: 'DELETE'
                });
                const data = await response.json();
                if (data.status === 'success') {
                    const index = conversations.findIndex(conv => conv.id === id);
                    if (index !== -1) {
                        conversations.splice(index, 1);
                        if (currentConversationId === id) {
                            if (conversations.length > 0) {
                                loadConversation(conversations[0].id);
                            } else {
                                startNewChat();
                            }
                        } else {
                            updateHistoryDisplay();
                        }
                    }
                }
            } catch (error) {
                console.error('删除对话失败:', error);
                alert('删除对话失败: ' + error.message);
            }
        }

        // 添加历史记录项的样式
        const styles = document.createElement('style');
        styles.textContent = `
            .history-item {
                position: relative;
            }
            
            .delete-chat {
                position: absolute;
                right: 8px;
                opacity: 0;
                background: none;
                border: none;
                cursor: pointer;
                padding: 4px 8px;
                border-radius: 4px;
                transition: all 0.2s;
            }
            
            .history-item:hover .delete-chat {
                opacity: 1;
            }
            
            .delete-chat:hover {
                background-color: rgba(239, 68, 68, 0.1);
                color: #EF4444;
            }
        `;
        document.head.appendChild(styles);
    </script>
</body>
</html> 